package com.mojo.concurrent.concurrent_02_lock;

/**
 * synchronized结合await方法
 *
 * @author <a href="mailto:sjj@jianzhimao.com">mojo</a>
 * copyright (C), 2013-2022, 广州九尾信息科技有限公司
 * @date 2022/3/17 15:18
 */
public class SynchronizationWait {
    public static void main(String[] args) {
        Thread t1 = new Thread(new ProThread(), "生产者线程");
        Thread t2 = new Thread(new SubThread(), "消费者线程");
        t2.start();
        t1.start();

    }
}

class Service {
    private static boolean flag = true;
    private final static Object obj = new Object();
    static Integer n = 0;

    //生产
    public void produce() {
        //1.加锁，释放锁
        //2.判断等待条件
        synchronized (obj) {
            if (flag) {
                try {
                    obj.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //3.执行逻辑
            System.out.println(Thread.currentThread().getName() + n++);
            //4.执行唤醒
            flag = true;
            obj.notify();
        }
    }

    public void consume() {
        //1.加锁，释放锁
        //2.判断等待条件
        synchronized (obj) {
            if (!flag) {
                try {
                    obj.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //3.执行逻辑
            System.out.println(Thread.currentThread().getName() + n--);
            //4.执行唤醒
            flag = false;
            obj.notify();
        }
    }
}

class ProThread implements Runnable {
    Service service = new Service();

    @Override
    public void run() {
        for (int i = 0; i < 50; i++) {
            service.produce();
        }
    }
}

class SubThread implements Runnable {
    Service service = new Service();

    @Override
    public void run() {
        for (int i = 0; i < 50; i++) {
            service.consume();
        }
    }
}